﻿using GalaSoft.MvvmLight.Messaging;
using ICSharpCode.AvalonEdit;
using JiveMessenger.AvalonEdit;
using JiveMessenger.ViewModels;
using NLog;
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Linq;
using System.Windows.Media.Animation;
using System.Windows.Media;


namespace JiveMessenger.CustomControls
{
    /// <summary>
    /// Interaction logic for PrivateMessageControl.xaml
    /// </summary>
    public partial class PrivateMessageControl : UserControl
    {
        private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
        public PrivateMessageControl()
        {

            InitializeComponent();
            if (DesignerProperties.GetIsInDesignMode(this))
                return;

            InitKeyBindings();

        }

        private void InitKeyBindings()
        {
            var locator = (ViewModelLocator)Application.Current.Resources["Locator"];
            KeyGestureConverter converter = new KeyGestureConverter();
            if (converter.IsValid((locator.CurrentClient.UserSettings.WinampKeyGesture)))
                this.WinampNowPlayingKeyBinding.Gesture = (KeyGesture)converter.ConvertFromString(locator.CurrentClient.UserSettings.WinampKeyGesture);
            if (converter.IsValid((locator.CurrentClient.UserSettings.SpotifyKeyGesture)))
                this.SpotifyNowPlayingKeyBinding.Gesture = (KeyGesture)converter.ConvertFromString(locator.CurrentClient.UserSettings.SpotifyKeyGesture);
        }

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            if (DesignerProperties.GetIsInDesignMode(this))
                return;

            ChatControl.ScrollOffset = ((ViewModelPrivateMessage)this.DataContext).ScrollOffset;
            ChatControl.AvalonConversation.ScrollToVerticalOffset(ChatControl.ScrollOffset);
            ((ViewModelChat)this.DataContext).IsInputTextFocused = true;

            Window win = Window.GetWindow(this);
            if (win != null)
            {
                win.Activated += Window_Activated;
                win.Deactivated += Window_Deactivated;
            }
            Messenger.Default.Register<NotificationMessage>(this, msg =>
            {
                var viewModelLocator = (ViewModelLocator)Application.Current.Resources["Locator"];
                switch (msg.Notification)
                {
                    case "InitKeyBindings":
                        this.InitKeyBindings();
                        break;
                    case "ScrollDocument":
                        if (msg.Sender == this.DataContext)
                            this.ChatControl.SetScrollbar();
                        break;
                    case "ForceScrollDocument":
                        this.ChatControl.ForceScrollNextLineToEnd = true;
                        this.ChatControl.SetScrollbar();
                        break;
                    case "RedrawChatWindow":
                        this.ChatControl.AvalonConversation.TextArea.TextView.Redraw();
                        break;
                }
            });
        }

        private void UserControl_Unloaded(object sender, RoutedEventArgs e)
        {
           // StopImagePreview();
            Messenger.Default.Unregister(this);
            Logger.Trace("PrivateMessageChatcontrol unloaded");
        }

        private void JivePrivateMessageControl_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (DesignerProperties.GetIsInDesignMode(this))
                return;

            if (e.OldValue != null)
            {
                ViewModelChat vm = (ViewModelChat)e.OldValue;
                bool isAtEnd = ChatControl.AvalonConversation.TextArea.TextView.VerticalOffset + ChatControl.AvalonConversation.TextArea.TextView.ActualHeight + 5 >= ChatControl.AvalonConversation.TextArea.TextView.DocumentHeight;
                vm.IsScrolledToEnd = isAtEnd;
                vm.ScrollOffset = ChatControl.AvalonConversation.VerticalOffset;
                foreach (ImageElementGenerator gen in ((ViewModelChat)vm).ConversationElementGenerators.Union(((ViewModelChat)vm).MessageInputElementGenerators).Where(x => x is ImageElementGenerator))
                {
                    gen.CleanCache();
                }
                Window win = Window.GetWindow(this);
                if (win != null)
                {
                    win.Activated -= Window_Activated;
                    win.Deactivated -= Window_Deactivated;
                }
                Logger.Trace("Storing scroll offset: " + vm.ScrollOffset);
            }
            if (e.NewValue != null)
            {
                ViewModelPrivateMessage vm = (ViewModelPrivateMessage)e.NewValue;
                if (vm.ContactListState == ContactListState.Short)
                {
                    if (this.ContactsGrid.Width == (double)Resources["ContactListWideWidth"])
                    {
                        Storyboard s = Resources["CollapseContactListWithoutAnim"] as Storyboard;
                        s.Begin();
                    }
                }
                else if (vm.ContactListState == ContactListState.Wide)
                {
                    if (this.ContactsGrid.Width == (double)Resources["ContactListShortWidth"])
                    {
                        Storyboard s = Resources["ExpandContactListWithoutAnim"] as Storyboard;
                        s.Begin();
                    }
                }
                this.Dispatcher.BeginInvoke(() =>
                {
                    if (!ChatControl.AvalonConversation.IsLoaded)
                    {
                        ChatControl.AvalonConversation.Loaded += AvalonConversation_Loaded;
                    }
                    else
                    {
                        SetScroll();
                    }
                });
                Logger.Trace("Tried to scroll to offset: " + vm.ScrollOffset);
            }
        }
        private void SetScroll()
        {
            ViewModelChat chatVm = (ViewModelChat)this.DataContext;
            if (chatVm.IsScrolledToEnd)
            {
                ChatControl.ForceScrollNextLineToEnd = true;

                ChatControl.SetScrollbar();
            }
            else
            {
                ChatControl.AvalonConversation.ScrollToVerticalOffset(((ViewModelChat)this.DataContext).ScrollOffset);
                Logger.Trace("Tried to scroll to offset: " + chatVm.ScrollOffset);
            }
        }
        void AvalonConversation_Loaded(object sender, RoutedEventArgs e)
        {
            ChatControl.AvalonConversation.Loaded -= AvalonConversation_Loaded;
            SetScroll();
        }
        private void ExpandGroupList_Completed(object sender, EventArgs e)
        {
            RenderOptions.SetBitmapScalingMode(this.MyContactContent, BitmapScalingMode.NearestNeighbor);
            RenderOptions.SetBitmapScalingMode(this.PmTargetContactContent, BitmapScalingMode.NearestNeighbor);
        }

        private void CollapseContactList_Completed(object sender, EventArgs e)
        {
            RenderOptions.SetBitmapScalingMode(this.MyContactContent, BitmapScalingMode.HighQuality);
            RenderOptions.SetBitmapScalingMode(this.PmTargetContactContent, BitmapScalingMode.HighQuality);
        }
        void Window_Deactivated(object sender, EventArgs e)
        {
            var vm = this.DataContext as ViewModelChat;
            if (vm != null)
                vm.IsFocused = false;

            this.ChatControl.AvalonConversation.TextArea.TextView.Redraw();
        }

        void Window_Activated(object sender, EventArgs e)
        {
            var vm = this.DataContext as ViewModelChat;
            if (vm != null)
                vm.IsFocused = true;

            this.ChatControl.AvalonConversation.TextArea.TextView.Redraw();
        }

        private void bnDownloadMessages_Click(object sender, RoutedEventArgs e)
        {
            ViewModelPrivateMessage vm = this.DataContext as ViewModelPrivateMessage;
            if (vm.IsDownloadMessagePopupOpen && this.bnDownloadMessages.IsChecked == false)
                vm.IsDownloadMessagePopupOpen = false;
            else if (!vm.IsDownloadMessagePopupOpen && this.bnDownloadMessages.IsChecked == true)
                vm.IsDownloadMessagePopupOpen = true;
        }
    }
}
